package consul

import (
	"fmt"
	"gitee.com/golang-lib/go-framework/core/log"
	"gitee.com/golang-lib/go-framework/register"
	"gitee.com/golang-lib/go-framework/utils"
	consulapi "github.com/hashicorp/consul/api"
	"net/http"
	"os"
	"strconv"
)

type ConsulSrvRegister struct {
	consulCli *consulapi.Client
}

func NewConsulSrvRegister(addr, token string) (csr *ConsulSrvRegister, err error) {
	config := consulapi.DefaultConfig()
	config.Address = addr
	config.Token = token

	csr = &ConsulSrvRegister{}
	csr.consulCli, err = consulapi.NewClient(config)
	if err != nil {
		return
	}

	return csr, nil
}

func (csr *ConsulSrvRegister) RegisterService(reg *register.Registration) (err error) {
	registration := &consulapi.AgentServiceRegistration{
		ID:      reg.ServiceID,
		Name:    reg.ServiceName,
		Port:    reg.ServicePort,
		Tags:    reg.Tags,
		Address: reg.ServiceHost,
	}

	if reg.ServiceID == "" {
		registration.ID = fmt.Sprintf("%s_%d", reg.ServiceName, reg.ServicePort)
	}

	check := &consulapi.AgentServiceCheck{
		HTTP:                           fmt.Sprintf("http://%s:%d/v1/health", reg.ServiceHost, reg.ServicePort),
		Timeout:                        "5s",
		Interval:                       "5s",
		DeregisterCriticalServiceAfter: reg.DeRegisterAfter,
	}
	registration.Check = check

	return csr.consulCli.Agent().ServiceRegister(registration)
}

func HealthHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	_, _ = fmt.Fprintf(w, "Hello, you've hit %s\n", r.URL.Path)
}

func RegisterConsulSrv(conf *register.Config, serviceName string) error {
	envPort := os.Getenv("PORT_HTTP")
	if envPort == "" {
		envPort = "80"
	}
	sr, err := NewConsulSrvRegister(conf.RegSrv, conf.Token)
	if err != nil {
		log.Warnf("NewConsulSrvRegister failed, err: %v", err)
		return err
	}

	reg := &register.Registration{}
	reg.ServiceName = serviceName
	if conf.Host != "" {
		reg.ServiceHost = conf.Host
	} else if hostname, err := os.Hostname(); err != nil {
		reg.ServiceHost = utils.GetLocalIP()
	} else {
		reg.ServiceHost = hostname
	}
	if conf.Port != 0 {
		reg.ServicePort = conf.Port
	} else {
		reg.ServicePort, _ = strconv.Atoi(envPort)
	}
	reg.Tags = append(reg.Tags, "platform", serviceName)

	err = sr.RegisterService(reg)
	if err != nil {
		log.Warnf("RegisterService failed, err: %v", err)
		return err
	} else {
		log.Info("RegisterService succ")
	}
	return nil
}
